package com.onehouse.domain.room.service;

import com.onehouse.domain.room.model.DailyRoomPriceSetEntity;
import com.onehouse.domain.room.model.RoomPriceEntity;
import com.onehouse.domain.room.repository.IRoomPriceRepository;
import com.onehouse.domain.room.repository.IRoomTypeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class RoomPriceService implements IRoomPriceService {
    @Autowired
    private IRoomPriceRepository roomPriceRepository;

    @Autowired
    private IRoomTypeRepository roomTypeRepository;

    public List<RoomPriceEntity> listAllRoomPrice() {
        return roomPriceRepository.selectList(null, null);
    }

    public List<DailyRoomPriceSetEntity> listRoomPriceByDateRange(LocalDate startTime, LocalDate endTime) {
        if (startTime == null || endTime == null) {
            throw new IllegalArgumentException("开始时间和结束时间不能为空");
        }
        if (startTime.isAfter(endTime)) {
            throw new IllegalArgumentException("开始时间不能晚于结束时间");
        }
        // 获取指定日期范围内的所有价格记录
        List<RoomPriceEntity> roomPrices = roomPriceRepository.selectList(startTime, endTime);
        
        // 获取所有房型的基础价格
        Map<Long, BigDecimal> roomTypeBasePrices = roomTypeRepository.selectList().stream()
                .collect(Collectors.toMap(
                        roomType -> roomType.getTypeId(),
                        roomType -> roomType.getBasePrice()
                ));

        // 按日期分组转换为DailyRoomPriceSetEntity列表
        Map<LocalDate, DailyRoomPriceSetEntity> dailyPriceMap = new HashMap<>();
        
        // 遍历日期范围内的每一天
        LocalDate currentDate = startTime;
        while (!currentDate.isAfter(endTime)) {
            DailyRoomPriceSetEntity dailyPrice = DailyRoomPriceSetEntity.builder()
                    .date(currentDate)
                    .roomPrices(new ArrayList<>())
                    .build();
            dailyPriceMap.put(currentDate, dailyPrice);
            currentDate = currentDate.plusDays(1);
        }
        
        // 添加已有的价格记录
        for (RoomPriceEntity price : roomPrices) {
            dailyPriceMap.get(price.getDate()).addRoomPriceEntity(price);
        }

        // 对于没有价格记录的日期，使用基础价格
        for (DailyRoomPriceSetEntity dailyPrice : dailyPriceMap.values()) {
            Set<Long> existingRoomTypes = dailyPrice.getRoomPrices().stream()
                    .map(RoomPriceEntity::getRoomTypeId)
                    .collect(Collectors.toSet());
            
            // 为没有价格记录的房型添加基础价格
            for (Map.Entry<Long, BigDecimal> entry : roomTypeBasePrices.entrySet()) {
                Long roomTypeId = entry.getKey();
                if (!existingRoomTypes.contains(roomTypeId)) {
                    RoomPriceEntity basePrice = RoomPriceEntity.builder()
                            .roomTypeId(roomTypeId)
                            .price(entry.getValue())
                            .date(dailyPrice.getDate())
                            .build();
                    dailyPrice.addRoomPriceEntity(basePrice);
                }
            }
        }
        
        return new ArrayList<>(dailyPriceMap.values());
    }

    public int createRoomPrice(RoomPriceEntity roomPriceEntity) {
        if (roomPriceEntity == null) {
            throw new IllegalArgumentException("房间价格信息不能为空");
        }
        if (roomPriceEntity.getRoomTypeId() == null) {
            throw new IllegalArgumentException("房间类型ID不能为空");
        }
        // 验证房间类型是否存在
        if (!roomTypeRepository.selectById(roomPriceEntity.getRoomTypeId()).isPresent()) {
            throw new IllegalArgumentException("指定的房间类型不存在");
        }
        if (roomPriceEntity.getPrice() == null || roomPriceEntity.getPrice().signum() <= 0) {
            throw new IllegalArgumentException("房间价格必须大于0");
        }
        if (roomPriceEntity.getDate() == null) {
            throw new IllegalArgumentException("价格生效日期不能为空");
        }

        return roomPriceRepository.insert(roomPriceEntity);
    }

    public int createRoomPriceByDateRange(RoomPriceEntity roomPriceEntity, LocalDate startTime, LocalDate endTime) {
        if (roomPriceEntity == null) {
            throw new IllegalArgumentException("房间价格信息不能为空");
        }
        if (roomPriceEntity.getRoomTypeId() == null) {
            throw new IllegalArgumentException("房间类型ID不能为空");
        }
        // 验证房间类型是否存在
        if (!roomTypeRepository.selectById(roomPriceEntity.getRoomTypeId()).isPresent()) {
            throw new IllegalArgumentException("指定的房间类型不存在");
        }
        if (roomPriceEntity.getPrice() == null || roomPriceEntity.getPrice().signum() <= 0) {
            throw new IllegalArgumentException("房间价格必须大于0");
        }
        if (startTime == null || endTime == null) {
            throw new IllegalArgumentException("开始时间和结束时间不能为空");
        }
        if (startTime.isAfter(endTime)) {
            throw new IllegalArgumentException("开始时间不能晚于结束时间");
        }

        return roomPriceRepository.insertByDateRange(roomPriceEntity, startTime, endTime);
    }

    public int updateRoomPrice(RoomPriceEntity roomPriceEntity) {
        if (roomPriceEntity == null) {
            throw new IllegalArgumentException("房间价格信息不能为空");
        }
        if (roomPriceEntity.getRoomTypeId() == null) {
            throw new IllegalArgumentException("房间类型ID不能为空");
        }
        // 验证房间类型是否存在
        if (!roomTypeRepository.selectById(roomPriceEntity.getRoomTypeId()).isPresent()) {
            throw new IllegalArgumentException("指定的房间类型不存在");
        }
        if (roomPriceEntity.getPrice() == null || roomPriceEntity.getPrice().signum() <= 0) {
            throw new IllegalArgumentException("房间价格必须大于0");
        }
        if (roomPriceEntity.getDate() == null) {
            throw new IllegalArgumentException("价格生效日期不能为空");
        }

        // 查询指定房型和日期的价格记录是否存在
        Optional<RoomPriceEntity> existingPrice = roomPriceRepository.selectByTypeAndDate(roomPriceEntity);
        
        // 如果记录不存在，则创建新记录
        if (!existingPrice.isPresent()) {
            return createRoomPrice(roomPriceEntity);
        }
        
        // 如果记录存在，则更新记录
        roomPriceEntity.setPriceId(existingPrice.get().getPriceId());
        return roomPriceRepository.updateByDate(roomPriceEntity);
    }

    public int updateRoomPriceByDateRange(RoomPriceEntity roomPriceEntity, LocalDate startTime, LocalDate endTime) {
        if (roomPriceEntity == null) {
            throw new IllegalArgumentException("房间价格信息不能为空");
        }
        if (roomPriceEntity.getRoomTypeId() == null) {
            throw new IllegalArgumentException("房间类型ID不能为空");
        }
        if (roomPriceEntity.getPrice() == null || roomPriceEntity.getPrice().signum() <= 0) {
            throw new IllegalArgumentException("房间价格必须大于0");
        }
        if (startTime == null || endTime == null) {
            throw new IllegalArgumentException("开始时间和结束时间不能为空");
        }
        if (startTime.isAfter(endTime)) {
            throw new IllegalArgumentException("开始时间不能晚于结束时间");
        }

        int updatedCount = 0;
        LocalDate currentDate = startTime;
        while (!currentDate.isAfter(endTime)) {
            roomPriceEntity.setDate(currentDate);
            updatedCount += updateRoomPrice(roomPriceEntity);
            currentDate = currentDate.plusDays(1);
        }
        return updatedCount;
    }

    public int deleteRoomPrice(Long priceId) {
        if (priceId == null) {
            throw new IllegalArgumentException("价格ID不能为空");
        }
        return roomPriceRepository.deleteById(priceId);
    }
}